package com.moorror.cola.strategy.plugin.markers;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.cola.extension.BizScenario;
import com.alibaba.cola.extension.ExtensionCoordinate;
import com.alibaba.cola.extension.ExtensionExecutor;
import com.alibaba.cola.extension.ExtensionPointI;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.util.NotNullFactory;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.psi.*;
import com.moorror.cola.strategy.plugin.bean.Constants;
import com.moorror.cola.strategy.plugin.bean.ExtensionPointIWrap;
import com.moorror.cola.strategy.plugin.bean.PsiElementWrapper;
import com.moorror.cola.strategy.plugin.utils.ColaStrategyPluginPsiUtils;
import com.moorror.cola.strategy.plugin.utils.ProjectServiceUtils;
import com.moorror.cola.strategy.plugin.view.component.CSActionToolbar;
import com.moorror.cola.strategy.plugin.view.window.CSPluginWindowFactory;
import org.apache.commons.compress.utils.Lists;
import org.jetbrains.annotations.NotNull;

import java.awt.event.MouseEvent;
import java.util.List;
import java.util.Map;

/**
 * @Author jiyanghuang
 * @Date 2023/7/15 16:12
 */
public class ColaHandlerLineMarkerProvider implements LineMarkerProvider {

    @Override
    public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement psiElement) {
        if(psiElement instanceof PsiMethodCallExpression){
            PsiMethodCallExpression psiMethodCallExpression = (PsiMethodCallExpression)psiElement;
            PsiClass psiClass = ColaStrategyPluginPsiUtils.firstChildPsiReferenceExpression(psiElement, 2);
            if(null != psiClass){
                if (ExtensionExecutor.class.getName().equals(psiClass.getQualifiedName())) {
                    return find(psiMethodCallExpression);
                }
            }
        }
        return null;
    }

    public LineMarkerInfo find(PsiMethodCallExpression psiMethodCallExpression) {
        for (PsiElement psiElement : psiMethodCallExpression.getChildren()) {
            if(psiElement instanceof PsiExpressionList){
                PsiExpressionList psiExpressionList = (PsiExpressionList) psiElement;
                for (PsiElement ch : psiExpressionList.getChildren()) {
                    if (ch instanceof PsiClassObjectAccessExpression) {
                        PsiClassObjectAccessExpression objectAccess = (PsiClassObjectAccessExpression) ch;
                        if (objectAccess.getText().endsWith(".class")) {
                            String fullName = objectAccess.getType().getCanonicalText();
                            String findName = fullName.substring("java.lang.Class<".length(), fullName.length() - 1);
                            PsiClass psiClass = ColaStrategyPluginPsiUtils.findPsiClass(psiMethodCallExpression.getProject(), findName);
                            System.out.println(psiClass);
                            boolean re = ColaStrategyPluginPsiUtils.isInheritor(psiClass.getQualifiedName(), ExtensionPointI.class.getName(), psiMethodCallExpression.getProject());
                            if (re) {
                                return buildMarkerInfo(psiMethodCallExpression, findName);
                            }
                            return null;
                        }
                    }
                }
            }
        }
        return null;
    }

    public LineMarkerInfo buildMarkerInfo(PsiMethodCallExpression psiMethodCallExpression, String findName) {

        PsiElement linkMarkEle = ColaStrategyPluginPsiUtils.psiIdentifier(psiMethodCallExpression);

        LineMarkerInfo info = new LineMarkerInfo(linkMarkEle, linkMarkEle.getTextRange(), AllIcons.Actions.ShowReadAccess, null, new GutterIconNavigationHandler() {
            @Override
            public void navigate(MouseEvent e, PsiElement elt) {
                List<PsiElementWrapper> psiElementWrappers = Lists.newArrayList();
                String emptyText = "获取不到实现类，请检查业务身份、产品、场景是否设置正确";
                CSActionToolbar bdefActionToolbar = ProjectServiceUtils.instance(psiMethodCallExpression.getProject(), CSActionToolbar.class);
                if(bdefActionToolbar.openMarker()){
                    Map<ExtensionCoordinate, ExtensionPointI> extensionPointIMap = CSPluginWindowFactory.extensionRepository.getExtensionRepo();
                    for (Map.Entry<ExtensionCoordinate, ExtensionPointI> entry : extensionPointIMap.entrySet()) {
                        String key = BeanUtil.getProperty(entry.getKey(), "extensionPointName");
                        if (findName.equals(key)) {
                            psiElementWrappers.addAll(ExtensionPointIWrap.convert((ExtensionPointIWrap)entry.getValue()));
                        }
                    }
                }else{
                    ExtensionCoordinate extensionCoordinate = new ExtensionCoordinate(findName, bdefActionToolbar.bizId());
                    ExtensionPointI extensionPointI = CSPluginWindowFactory.extensionRepository.getExtensionRepo().get(extensionCoordinate);
                    if(null != extensionPointI){
                        psiElementWrappers = ExtensionPointIWrap.convert((ExtensionPointIWrap)extensionPointI);
                    }
                }

                List<PsiElementWrapper> psiElementWrappersFinal = null == psiElementWrappers ? Lists.newArrayList() : psiElementWrappers;

                if(1 == psiElementWrappersFinal.size()){
                    psiElementWrappersFinal.add(PsiElementWrapper.ofBlank(psiElementWrappersFinal.get(0).getElement().getParent()));
                }

                //
                ColaNavigationGutterIconRenderer re = new ColaNavigationGutterIconRenderer(
                        AllIcons.Actions.ShowWriteAccess,
                        "实现类列表",
                        "toolTipText",
                        emptyText,
                        NotNullLazyValue.createValue(new NotNullFactory<List<PsiElementWrapper>>() {
                            @Override
                            public @NotNull
                            List<PsiElementWrapper> create() {
                                return psiElementWrappersFinal;
                            }
                        }));
                re.createLineMarkerInfo(elt);
                re.navigate(e, psiMethodCallExpression);
            }
        }, GutterIconRenderer.Alignment.LEFT, () -> {
            return "testName";
        });
        return info;
    }
}
